<?php
// +----------------------------------------------------------------------
// | OneKeyAdmin [ Believe that you can do better ]
// +----------------------------------------------------------------------
// | Copyright (c) 2020-2023 http://onekeyadmin.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: MUKE <513038996@qq.com>
// +----------------------------------------------------------------------
namespace app\admin\controller;

use PDO;
use onekey\File;
use think\facade\Db;
use think\facade\View;
use app\admin\BaseController;
use app\admin\model\AdminMenu;
use app\admin\model\Curd as CurdModel;
/**
 * 一键生成代码
 */
class Curd extends BaseController
{
    /**
     * 显示资源列表
     */
    public function index()
    {
        if ($this->request->isPost()) {
            $input = input('post.');
            $count = CurdModel::withSearch(['keyword'], $input)->count();
            $data  = CurdModel::withSearch(['keyword'], $input)->order('name', 'desc')->page($input['page'], $input['pageSize'])->select();
            $publicMenu = [];
            foreach ($this->request->menu as $key => $value) {
                if ($value['ifshow'] === 1) {
                    array_push($publicMenu, $value);
                }
            }
            return json(['status' => 'success', 'message' => '获取成功', 'data' => $data, 'count' => $count, 'publicMenu' => $publicMenu]);
        } else {
            return View::fetch();
        }
    }
    
    /**
     * 保存指定资源
     */
    public function save()
    {
        if ($this->request->isPost()) {
            $input = input('post.');
            if (strstr($input['name'], 'mk_') === false) {
                return json(['status' => 'error', 'message' => '数据表名前缀必须以mk_开头']);
            }
            if (CurdModel::where('name', $input['name'])->value('id')) {
                return json(['status' => 'error', 'message' => '数据表已经存在，无法创建']);
            }
            // 生成数据表
            $name  = $input['name'];
            $field = $input['field'];
            $primary = "";
            $sql  = "";
            $sql .= "CREATE TABLE IF NOT EXISTS `{$name}` (";
            foreach ($field as $key => $val) {
                $auto = "";
                if (! empty($val['key']) && $val['key'] == "PRI") {
                    $auto = " AUTO_INCREMENT";
                    $primary = $val['prop'];
                }
                // 防止拦截
                $fieldType = $val['field'] == 'varchar' ? 'varchar(255)' : $val['field'];
                $sql .= "`{$val['prop']}` {$fieldType} NOT NULL{$auto},";
            }
            $sql .= "PRIMARY KEY (`{$primary}`)";
            $sql .= ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;";
            $sqlInfo = "mysql:dbname=".env('database.database').";host=".env('database.hostname')."";
            $sqlDb   = new PDO($sqlInfo, env('database.username'), env('database.password'));
            $sqlDb->setAttribute(PDO::ATTR_EMULATE_PREPARES, 0);
            $sqlDb->exec($sql);
            // 记录当前数据
            CurdModel::create($input);
            // 生成后台控制器、模型、视图、API、路由、菜单权限
            $viewPath = str_replace('mk_','', $name);
            $path     = ucwords(str_replace('_', ' ', $viewPath));
            $path     = str_replace(' ','',lcfirst($path));
            $class    = ucfirst($path);
            include(app_path() . "addons/Curd.php");
            // 后台
            File::create(root_path() . "app/admin/model/$class.php", $admminModel);
            File::create(root_path() . "app/admin/view/$viewPath/index.html", $adminView);
            File::create(root_path() . "app/admin/controller/$class.php", $adminController);
            File::create(root_path() . "app/admin/validate/$class.php", $adminValidate);
            // API
            File::create(root_path() . "app/api/controller/$class.php", $apiController);
            File::create(root_path() . "app/api/validate/$class.php", $apiValidate);
            File::create(root_path() . "app/api/model/$class.php", $apiModel);
            // 菜单
            $menu = AdminMenu::where('path', $path . '/index')->where('pid', 0)->find();
            if (! $menu) {
                $menuParent = AdminMenu::create([
                    'pid'        => 0,
                    'title'      => empty($input['title']) ? '未命名' : $input['title'],
                    'icon'       => $input['cover'],
                    'path'       => $path . '/index',
                    'sort'       => 0,
                    'ifshow'     => 1,
                    'logwriting' => 0,
                    'type'       => '',
                ]);
            } else {
                $menu->title = $input['title'];
                $menu->icon  = $input['cover'];
                $menu->save();
            }
            if (! AdminMenu::where('path', $path . '/index')->value('id')) {
                AdminMenu::create([
                    'pid'        => $menuParent['id'],
                    'title'      => '查看',
                    'icon'       => '',
                    'path'       => $path . '/index',
                    'sort'       => 0,
                    'ifshow'     => 0,
                    'logwriting' => 0,
                    'type'       => '',
                ]);
            }
            if (! AdminMenu::where('path', $path . '/update')->value('id')) {
                AdminMenu::create([
                    'pid'        => $menuParent['id'],
                    'title'      => '编辑',
                    'icon'       => '',
                    'path'       => $path . '/update',
                    'sort'       => 0,
                    'ifshow'     => 0,
                    'logwriting' => 1,
                    'type'       => '',
                ]);
            }
            if (! AdminMenu::where('path', $path . '/save')->value('id')) {
                AdminMenu::create([
                    'pid'        => $menuParent['id'],
                    'title'      => '添加',
                    'icon'       => '',
                    'path'       => $path . '/save',
                    'sort'       => 0,
                    'ifshow'     => 0,
                    'logwriting' => 1,
                    'type'       => '',
                ]);
            }
            if (! AdminMenu::where('path', $path . '/delete')->value('id')) {
                AdminMenu::create([
                    'pid'        => $menuParent['id'],
                    'title'      => '删除',
                    'icon'       => '',
                    'path'       => $path . '/delete',
                    'sort'       => 0,
                    'ifshow'     => 0,
                    'logwriting' => 1,
                    'type'       => '',
                ]);
            }
            return json(['status' => 'success', 'message' => '生成成功']);
        }
    }
    
    /**
     * 保存更新的资源
     */
    public function update()
    {
        if ($this->request->isPost()) {
            $input = input('post.');
            $old   = CurdModel::find($input['id']);
            if (strstr($input['name'], 'mk_') === false) {
                return json(['status' => 'error', 'message' => '数据表名前缀必须以mk_开头']);
            }
            if ($old['name'] != $input['name']) {
                // 删除多余文件
                $oldName     = $old['name'];
                $oldViewPath = str_replace('mk_','', $oldName);
                $oldPath     = ucwords(str_replace('_', ' ', $oldViewPath));
                $oldPath     = str_replace(' ','',lcfirst($oldPath));
                $oldClass    = ucfirst($oldPath);
                File::delDirAndFile(root_path() . "app/admin/view/$oldViewPath");
                if (is_file(root_path() . "app/admin/model/$oldClass.php"))unlink(root_path() . "app/admin/model/$oldClass.php");
                if (is_file(root_path() . "app/admin/controller/$oldClass.php"))unlink(root_path() . "app/admin/controller/$oldClass.php");
                if (is_file(root_path() . "app/admin/validate/$oldClass.php"))unlink(root_path() . "app/admin/validate/$oldClass.php");
                if (is_file(root_path() . "app/api/controller/$oldClass.php"))unlink(root_path() . "app/api/controller/$oldClass.php");
                if (is_file(root_path() . "app/api/validate/$oldClass.php"))unlink(root_path() . "app/api/validate/$oldClass.php");
                if (is_file(root_path() . "app/api/model/$oldClass.php"))unlink(root_path() . "app/api/model/$oldClass.php");
                // 删除多余菜单
                AdminMenu::where('path', 'like', $oldPath . '/%')->delete();
                // 修改数据表名
                $sqlInfo = "mysql:dbname=".env('database.database').";host=".env('database.hostname')."";
                $sqlDb   = new PDO($sqlInfo, env('database.username'), env('database.password'));
                $sqlDb->setAttribute(PDO::ATTR_EMULATE_PREPARES, 0);
                $sqlDb->exec("ALTER TABLE {$old['name']} RENAME {$input['name']}");
            }
            CurdModel::update($input);
            // 生成后台控制器、模型、视图、API、路由、菜单权限
            $name     = $input['name'];
            $viewPath = str_replace('mk_','', $name);
            $path     = ucwords(str_replace('_', ' ', $viewPath));
            $path     = str_replace(' ','',lcfirst($path));
            $class    = ucfirst($path);
            $field    = $input['field'];
            include(app_path() . "addons/Curd.php");
            // 后台
            File::create(root_path() . "app/admin/view/$viewPath/index.html", $adminView);
            File::create(root_path() . "app/admin/model/$class.php", $admminModel);
            File::create(root_path() . "app/admin/controller/$class.php", $adminController);
            File::create(root_path() . "app/admin/validate/$class.php", $adminValidate);
            // API
            File::create(root_path() . "app/api/controller/$class.php", $apiController);
            File::create(root_path() . "app/api/validate/$class.php", $apiValidate);
            File::create(root_path() . "app/api/model/$class.php", $apiModel);
            // 菜单
            $menu = AdminMenu::where('path', $path . '/index')->where('pid', 0)->find();
            if (! $menu) {
                $menuParent = AdminMenu::create([
                    'pid'        => 0,
                    'title'      => empty($input['title']) ? '未命名' : $input['title'],
                    'icon'       => $input['cover'],
                    'path'       => $path . '/index',
                    'sort'       => 0,
                    'ifshow'     => 1,
                    'logwriting' => 0,
                    'type'       => '',
                ]);
            } else {
                $menu->title = $input['title'];
                $menu->icon  = $input['cover'];
                $menu->save();
            }
            if (! AdminMenu::where('path', $path . '/index')->value('id')) {
                AdminMenu::create([
                    'pid'        => $menuParent['id'],
                    'title'      => '查看',
                    'icon'       => '',
                    'path'       => $path . '/index',
                    'sort'       => 0,
                    'ifshow'     => 0,
                    'logwriting' => 0,
                    'type'       => '',
                ]);
            }
            if (! AdminMenu::where('path', $path . '/update')->value('id')) {
                AdminMenu::create([
                    'pid'        => $menuParent['id'],
                    'title'      => '编辑',
                    'icon'       => '',
                    'path'       => $path . '/update',
                    'sort'       => 0,
                    'ifshow'     => 0,
                    'logwriting' => 1,
                    'type'       => '',
                ]);
            }
            if (! AdminMenu::where('path', $path . '/save')->value('id')) {
                AdminMenu::create([
                    'pid'        => $menuParent['id'],
                    'title'      => '添加',
                    'icon'       => '',
                    'path'       => $path . '/save',
                    'sort'       => 0,
                    'ifshow'     => 0,
                    'logwriting' => 1,
                    'type'       => '',
                ]);
            }
            if (! AdminMenu::where('path', $path . '/delete')->value('id')) {
                AdminMenu::create([
                    'pid'        => $menuParent['id'],
                    'title'      => '删除',
                    'icon'       => '',
                    'path'       => $path . '/delete',
                    'sort'       => 0,
                    'ifshow'     => 0,
                    'logwriting' => 1,
                    'type'       => '',
                ]);
            }
            return json(['status' => 'success', 'message' => '生成成功']);
        }
    }
    
    /**
     * 添加数据表字段
     */
    public function saveField()
    {
        if ($this->request->isPost()) {
            $input = input('post.');
            // 防止拦截
            $field = $input['field'] == 'varchar' ? 'varchar(255)' : $input['field'];
            $sqlInfo = "mysql:dbname=".env('database.database').";host=".env('database.hostname')."";
            $sqlDb   = new PDO($sqlInfo, env('database.username'), env('database.password'));
            $sqlDb->setAttribute(PDO::ATTR_EMULATE_PREPARES, 0);
            $sqlDb->exec("ALTER TABLE {$input['table']} ADD {$input['prop']} {$field} NOT NULL;");
            return json(['status' => 'success', 'message' => '添加成功']);
        }
    }
    
    /**
     * 更新数据表字段
     */
    public function updateField()
    {
        if ($this->request->isPost()) {
            $input = input('post.');
            $auto  = '';
            if (! empty($input['key']) && $input['key'] == "PRI") {
                $auto = " AUTO_INCREMENT";
            }
            // 防止拦截
            $field = $input['field'] == 'varchar' ? 'varchar(255)' : $input['field'];
            $sqlInfo = "mysql:dbname=".env('database.database').";host=".env('database.hostname')."";
            $sqlDb   = new PDO($sqlInfo, env('database.username'), env('database.password'));
            $sqlDb->setAttribute(PDO::ATTR_EMULATE_PREPARES, 0);
            if (empty($input['oldProp'])) {
                $alter = "ALTER TABLE {$input['table']} MODIFY COLUMN {$input['prop']} {$field};";
            } else {
                $alter = "ALTER TABLE {$input['table']} CHANGE {$input['oldProp']} {$input['prop']} {$field} NOT NULL{$auto};";
            }
            $sqlDb->exec($alter);
            return json(['status' => 'success', 'message' => '修改成功']);
        }
    }
    
    /**
     * 删除数据表字段
     */
    public function deleteField()
    {
        if ($this->request->isPost()) {
            $input = input('post.');
            $input = input('post.');
            $sqlInfo = "mysql:dbname=".env('database.database').";host=".env('database.hostname')."";
            $sqlDb   = new PDO($sqlInfo, env('database.username'), env('database.password'));
            $sqlDb->setAttribute(PDO::ATTR_EMULATE_PREPARES, 0);
            $sqlDb->exec("alter table {$input['table']} drop column {$input['prop']};");
            return json(['status' => 'success', 'message' => '删除成功']);
        }
    }
    
    /**
     * 删除指定资源
     */
    public function delete()
    {
        if ($this->request->isPost()) {
            $input = input('post.');
            $sqlInfo = "mysql:dbname=".env('database.database').";host=".env('database.hostname')."";
            $sqlDb   = new PDO($sqlInfo, env('database.username'), env('database.password'));
            $sqlDb->setAttribute(PDO::ATTR_EMULATE_PREPARES, 0);
            foreach ($input['rows'] as $key => $val) {
                // 删除多余文件
                $oldName     = $val['name'];
                $oldViewPath = str_replace('mk_','', $oldName);
                $oldPath     = ucwords(str_replace('_', ' ', $oldViewPath));
                $oldPath     = str_replace(' ','',lcfirst($oldPath));
                $oldClass    = ucfirst($oldPath);
                File::delDirAndFile(root_path() . "app/admin/view/$oldViewPath");
                if (is_file(root_path() . "app/admin/model/$oldClass.php"))unlink(root_path() . "app/admin/model/$oldClass.php");
                if (is_file(root_path() . "app/admin/controller/$oldClass.php"))unlink(root_path() . "app/admin/controller/$oldClass.php");
                if (is_file(root_path() . "app/admin/validate/$oldClass.php"))unlink(root_path() . "app/admin/validate/$oldClass.php");
                if (is_file(root_path() . "app/api/controller/$oldClass.php"))unlink(root_path() . "app/api/controller/$oldClass.php");
                if (is_file(root_path() . "app/api/validate/$oldClass.php"))unlink(root_path() . "app/api/validate/$oldClass.php");
                if (is_file(root_path() . "app/api/model/$oldClass.php"))unlink(root_path() . "app/api/model/$oldClass.php");
                // 删除多余菜单
                AdminMenu::where('path', 'like', $oldPath . '/%')->delete();
                // 删除数据库
                $sqlDb->exec("DROP TABLE IF EXISTS {$oldName}");
                CurdModel::destroy($val['id']);
            }
            // 删除数据表
            return json(['status' => 'success', 'message' => '删除成功']);
        }
    }
}
